package br.com.fogas.medicao.activity;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import br.com.fogas.medicao.R;
import br.com.fogas.medicao.activity.dto.RetornoAutorizacaoNotaDto;
import br.com.fogas.medicao.application.ApplicationFogas;
import br.com.fogas.medicao.application.Constants;
import br.com.fogas.medicao.application.LoadFragment;
import br.com.fogas.medicao.menu.MenuDto;
import br.com.fogas.medicao.menu.MenuAdapter;
import br.com.fogas.medicao.menu.MenuDtoItem;
import br.com.fogas.utils.FogasUtility;
import br.com.fogas.utils.StringUtility;
import butterknife.ButterKnife;
import butterknife.InjectView;
import android.app.Activity;
import android.content.res.Configuration;
import android.os.Bundle;
import android.support.v4.app.ActionBarDrawerToggle;
import android.support.v4.app.FragmentActivity;
import android.support.v4.widget.DrawerLayout;
import android.util.Log;
import android.view.Menu;
import android.view.MenuItem;
import android.view.View;
import android.widget.AdapterView;
import android.widget.ImageView;
import android.widget.ListView;
import android.widget.TextView;

public class MainActivity extends FragmentActivity {
	
	private CharSequence menuDrawerTitle, menuTitle;
	
	@InjectView(R.id.drawer_layout) 
	DrawerLayout menuDrawerLayout;
	
	private ActionBarDrawerToggle menuDrawerToggle;

	private Map<String, MenuDto> menuItemsMap;
	private List<MenuDto> menuItems;
	
	@InjectView(R.id.list_slidermenu) 
	ListView menuListView;
	private MenuAdapter menuAdapter;
	
	private MenuDto itemSelected;
	
	@Override
    public void onBackPressed() {
		int backStackEntryCount = getSupportFragmentManager().getBackStackEntryCount();
		
		if (backStackEntryCount == 1) {
			finish();
		} else {
			super.onBackPressed();
		}
    }
	
	@Override
	protected void onDestroy() {
		try {
			super.onDestroy();
		} catch (Exception e) {
			e.printStackTrace();
		}
	}
		
	@Override
	protected void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		setContentView(R.layout.menu_main);
		ButterKnife.inject(this);
		
		menuTitle = getTitle();
		menuDrawerTitle = getString(R.string.menu_open);
		
		menuItems();
		menuAdapter = new MenuAdapter(this, menuItems);
		menuListView.addHeaderView(menuTopo());
		menuListView.addFooterView(menuRodape());
		menuListView.setAdapter(menuAdapter);
		menuListView.setOnItemClickListener(new SlideMenuClickListener());
		
		getActionBar().setDisplayHomeAsUpEnabled(true);
        getActionBar().setHomeButtonEnabled(true);
        
        menuDrawerToggle = new MenuActionBarDrawerToggle(this, menuDrawerLayout,
				R.drawable.ic_drawer, //nav menu toggle icon
				R.string.menu_open, // nav drawer open - description for accessibility
				R.string.menu_close // nav drawer close - description for accessibility
		);
		menuDrawerLayout.setDrawerListener(menuDrawerToggle);
        
        if(getIntent().getSerializableExtra(Constants.RETORNO_AUTORIZACAO_NOTA) != null) {
        	RetornoAutorizacaoNotaDto retornoNota = (RetornoAutorizacaoNotaDto) 
        			getIntent().getSerializableExtra(Constants.RETORNO_AUTORIZACAO_NOTA);
        	conclusaoFaturamento(retornoNota);
        } else if (savedInstanceState == null) {
        	MenuDto menuDto = getMenuPorTag(Constants.FRAGMENT_PLANO_HOME);
			displayView(menuDto); 
        }
	}
	
	private class MenuActionBarDrawerToggle extends ActionBarDrawerToggle {

		public MenuActionBarDrawerToggle(Activity activity,
				DrawerLayout drawerLayout, int drawerImageRes,
				int openDrawerContentDescRes, int closeDrawerContentDescRes) {
			super(activity, drawerLayout, drawerImageRes, openDrawerContentDescRes, closeDrawerContentDescRes);
		}

		@Override
		public void onDrawerClosed(View drawerView) {
			getActionBar().setTitle(menuTitle);
			// calling onPrepareOptionsMenu() to show action bar icons
			invalidateOptionsMenu();
		}
		
		@Override
		public void onDrawerOpened(View drawerView) {
			getActionBar().setTitle(menuDrawerTitle);
			// calling onPrepareOptionsMenu() to hide action bar icons
			invalidateOptionsMenu();
		}
	}
	
	private class SlideMenuClickListener implements ListView.OnItemClickListener {
		@Override
		public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
			boolean firstLastClicked = (position == 0) || (position == (parent.getCount() - 1)); 
			if(firstLastClicked) {
				view.setBackgroundResource(R.drawable.menu_list_item_bg_normal);
				setItemSelected(itemSelected);
			} else {
				MenuDto menuDto = (MenuDto) parent.getItemAtPosition(position);
				displayView(menuDto);
			}
		}
	}
	
	/**
	 * Este metodo verifica a resposta do retorno da conclusao do faturamento se o cliente nao estiver bloqueado
	 * na Sefaz ou ocorreu algum erro na autorizacao on-line, ele redireciona para a tela de impressao, caso contrario 
	 * redireciona para a tela de simulacao informando o erro ocorrido para o bloqueio ou avisando que vai emitir
	 * em contigencia a nota.
	 * 
	 * @param retornoNota
	 * @author andre.nascimento
	 */
	private void conclusaoFaturamento(RetornoAutorizacaoNotaDto retornoNota) {
		MenuDto menuDto = new MenuDto();
		menuDto.setItem(new MenuDtoItem(R.drawable.ic_item, getString(R.string.title_fragment_plano_visitas)));
		menuDto.setTagFragment(Constants.FRAGMENT_CONCLUSAO_FATURAMENTO);
		
		if(retornoNota.isBloqueadoSefaz() || retornoNota.isEmitirContigencia()) {
	    	menuDto.setFragment(SimulacaoMedidorFragment.newInstance(retornoNota));
		} else {
	    	menuDto.setFragment(ImpressaoNotaFragment.newInstance(retornoNota.getNotaSimulacao()));
		}
		
		menuDto.setFragmentAddBackStack(true);
		menuDto.setPosition(1);
		displayView(menuDto);
	}
	
	private void menuItems() {
		this.menuItems = new ArrayList<MenuDto>();
		
		MenuDto menuDto = new MenuDto();
		menuDto.setItem(new MenuDtoItem(R.drawable.ic_item, getString(R.string.title_fragment_plano_visitas)));
		menuDto.setFragment(new PlanoHomeFragment());
		menuDto.setTagFragment(Constants.FRAGMENT_PLANO_HOME);
		menuDto.setFragmentAddBackStack(false);
		menuDto.setPosition(1);
		this.menuItems.add(menuDto);
		
		menuDto = new MenuDto();
		menuDto.setItem(new MenuDtoItem(R.drawable.ic_item, getString(R.string.title_fragment_notas_emitidas)));
		menuDto.setFragment(new NotasEmitidasFragment());
		menuDto.setTagFragment(Constants.FRAGMENT_NOTAS_EMITIDAS);
		menuDto.setFragmentAddBackStack(true);
		menuDto.setPosition(2);
		this.menuItems.add(menuDto);
		
		menuDto = new MenuDto();
		menuDto.setItem(new MenuDtoItem(R.drawable.ic_item, getString(R.string.title_fragment_config)));
		menuDto.setFragment(new ConfiguracaoFragment());
		menuDto.setTagFragment(Constants.FRAGMENT_CONFIGURACAO);
		menuDto.setFragmentAddBackStack(false);
		menuDto.setPosition(3);
		this.menuItems.add(menuDto);
		
		this.menuItemsMap = new HashMap<String, MenuDto>();
		for(MenuDto item: this.menuItems) {
			this.menuItemsMap.put(item.getTagFragment(), item);
		}
	}
	
	private View menuTopo() {
		View header = getLayoutInflater().inflate(R.layout.menu_list_item_top, null);
		ImageView imgMenuTopIcon = (ImageView) header.findViewById(R.id.imgMenuTopIcon);
		TextView tvMenuTopToken = (TextView) header.findViewById(R.id.tvMenuTopToken);
		TextView tvMenuTopUserName = (TextView) header.findViewById(R.id.tvMenuTopUserName);
		TextView tvMenuTopVersion = (TextView) header.findViewById(R.id.tvMenuTopVersion);
		
		String token = getString(R.string.menu_token);
		token = StringUtility.replace(token, "#TOKEN", ApplicationFogas.getInstance().getConfiguracao().getAppDados().getToken());
		String usuario = ApplicationFogas.getInstance().getConfiguracao().getAppDados().getUsuario();
		String versao = getString(R.string.menu_versao);
		versao = StringUtility.replace(versao, "#VERSAO", ApplicationFogas.getInstance().getConfiguracao().getAppDados().getVersao());
		
		imgMenuTopIcon.setImageResource(R.drawable.ic_user);
		tvMenuTopToken.setText(token);
		tvMenuTopUserName.setText(usuario);
		tvMenuTopVersion.setText(versao);
		
		return header;
	}
	
	private View menuRodape() {
		View bottom = getLayoutInflater().inflate(R.layout.menu_list_item_bottom, null);
		ImageView imgMenuBottomIcon = (ImageView) bottom.findViewById(R.id.imgMenuBottomIcon);
		TextView tvMenuBottomToken = (TextView) bottom.findViewById(R.id.tvMenuBottomToken);
		
		String data = FogasUtility.data.getStringByDateAndFormat(
				ApplicationFogas.getInstance().getConfiguracao().getAppDados().getDtSincronizacao(), 
				"dd/MM/yyyy HH:mm:ss");
		String sincronizacao = getString(R.string.menu_sincronizacao);
		sincronizacao = StringUtility.replace(sincronizacao, "#DATA", data);
		
		imgMenuBottomIcon.setImageResource(R.drawable.ic_sync);
		tvMenuBottomToken.setText(sincronizacao);
		
		return bottom;
	}
	
	@Override
	public boolean onOptionsItemSelected(MenuItem item) {
		if (menuDrawerToggle.onOptionsItemSelected(item)) {
			return true;
		} else {
			return super.onOptionsItemSelected(item);
		}
	}
	
	/*
	 * Called when invalidateOptionsMenu() is triggered
	 */
	@Override
	public boolean onPrepareOptionsMenu(Menu menu) {
		// if nav drawer is opened, hide the action items
		//boolean drawerOpen = menuDrawerLayout.isDrawerOpen(menuListView);
		//menu.findItem(R.id.action_settings).setVisible(!drawerOpen);
		return super.onPrepareOptionsMenu(menu);
	}
	
	@Override
	public void setTitle(CharSequence title) {
		menuTitle = title;
		getActionBar().setTitle(menuTitle);
	}

	/**
	 * When using the ActionBarDrawerToggle, you must call it during
	 * onPostCreate() and onConfigurationChanged()...
	 */
	@Override
	protected void onPostCreate(Bundle savedInstanceState) {
		super.onPostCreate(savedInstanceState);
		// Sync the toggle state after onRestoreInstanceState has occurred.
		menuDrawerToggle.syncState();
	}

	@Override
	public void onConfigurationChanged(Configuration newConfig) {
		super.onConfigurationChanged(newConfig);
		// Pass any configuration change to the drawer toggls
		menuDrawerToggle.onConfigurationChanged(newConfig);
	}
	
	private MenuDto getMenuPorTag(String tagFragment) {
		return menuItemsMap.get(tagFragment);
	}
	
	private void displayView(MenuDto menuDto) {
		if (menuDto.getFragment() != null) {
			LoadFragment load = new LoadFragment(getSupportFragmentManager());
			load.initializeFragment(
					menuDto.isFragmentAddBackStack(), 
					menuDto.getFragment(), 
					menuDto.getTagFragment());
			
			// update selected item and title, then close the drawer
			setItemSelected(menuDto);
			setTitle(menuDto.getItem().getTitle());
			itemSelected = menuDto;
			menuDrawerLayout.closeDrawer(menuListView);
		} else {
			Log.e("MainActivity", "Error in creating fragment");
		}
	}
	
	private void setItemSelected(MenuDto menuDto) {
		menuListView.setItemChecked(menuDto.getPosition(), true);
		menuListView.setSelection(menuDto.getPosition());
	}
}